/*
* $Id: KeyProcess.cpp 20 2010-01-19 15:40:42Z volok-aleksej@yandex.ru $
*
* Copyright 2009 by Volokitin Alexey
* All rights reserved
*
*/
#include "Common/include.h"
#include "KeyProcess.h"
#include "EditDraw.h"
#include "ComboBoxDraw.h"
#include "CheckBoxDraw.h"
#include "DateDraw.h"

/************************************************************************/
/*                          CKeyProcess                                 */
/************************************************************************/
CKeyProcess::CKeyProcess(CEditDraw* pEditDraw)
: m_pEditDraw(pEditDraw), m_pComboBoxDraw(NULL), m_pCheckBoxDraw(NULL), m_pDateDraw(NULL){}
CKeyProcess::CKeyProcess(CComboBoxDraw* pComboBoxDraw)
: m_pEditDraw(NULL), m_pComboBoxDraw(pComboBoxDraw), m_pCheckBoxDraw(NULL), m_pDateDraw(NULL){}
CKeyProcess::CKeyProcess(CCheckBoxDraw* pCheckBoxDraw)
: m_pEditDraw(NULL), m_pComboBoxDraw(NULL), m_pCheckBoxDraw(pCheckBoxDraw), m_pDateDraw(NULL){}
CKeyProcess::CKeyProcess(CDateDraw* pDateDraw)
:  m_pEditDraw(NULL), m_pComboBoxDraw(NULL), m_pCheckBoxDraw(NULL), m_pDateDraw(pDateDraw){}
CKeyProcess::~CKeyProcess(){}
bool CKeyProcess::IsProcess(unsigned int nChar, byte stateSysKey){
	return false;
}
bool CKeyProcess::Process(){
	return false;
}
/************************************************************************/
/*                            CArrawLeft                                */
/************************************************************************/
CArrawLeft::CArrawLeft(CEditDraw* pEditDraw)
: CKeyProcess(pEditDraw){}
CArrawLeft::CArrawLeft(CDateDraw* pDateDraw)
: CKeyProcess(pDateDraw){}
bool CArrawLeft::IsProcess(unsigned int nChar, byte stateSysKey){
	return nChar == VK_LEFT && !(stateSysKey&0x5);
}
bool CArrawLeft::Process(){
	if(m_pEditDraw){
		m_pEditDraw->OffsetCursor(-1);
		return true;
	}else if(m_pDateDraw){
		m_pDateDraw->OffsetDay(-1);
		return true;
	}
	return false;
}
/************************************************************************/
/*                            CArrawRight                                */
/************************************************************************/
CArrawRight::CArrawRight(CEditDraw* pEditDraw)
: CKeyProcess(pEditDraw){}
CArrawRight::CArrawRight(CDateDraw* pDateDraw)
: CKeyProcess(pDateDraw){}
bool CArrawRight::IsProcess(unsigned int nChar, byte stateSysKey){
	return nChar == VK_RIGHT && !(stateSysKey&0x5);
}
bool CArrawRight::Process(){
	if(m_pEditDraw){
		m_pEditDraw->OffsetCursor(1);
		return true;
	}else if(m_pDateDraw){
		m_pDateDraw->OffsetDay(1);
		return true;
	}
	return false;
}
/************************************************************************/
/*                            CArrawUp                                */
/************************************************************************/
CArrawUp::CArrawUp(CEditDraw* pEditDraw)
: CKeyProcess(pEditDraw){}
CArrawUp::CArrawUp(CComboBoxDraw* pComboBoxDraw)
: CKeyProcess(pComboBoxDraw){}
CArrawUp::CArrawUp(CDateDraw* pDateDraw)
: CKeyProcess(pDateDraw){}
bool CArrawUp::IsProcess(unsigned int nChar, byte stateSysKey){
	return nChar == VK_UP && !(stateSysKey&0x1);
}
bool CArrawUp::Process(){
	if(m_pEditDraw){
		int offset = m_pEditDraw->GetOffsetLine(true);
		if(!offset)
			return true;
		m_pEditDraw->OffsetCursor(offset);
		return true;
	}if(m_pComboBoxDraw){
		m_pComboBoxDraw->OffsetSelection(-1);
		return true;
	}else if(m_pDateDraw){
		m_pDateDraw->OffsetDay(-7);
		return true;
	}
	return false;
}
/************************************************************************/
/*                            CArrawDown                                */
/************************************************************************/
CArrawDown::CArrawDown(CEditDraw* pEditDraw)
: CKeyProcess(pEditDraw){}
CArrawDown::CArrawDown(CDateDraw* pDateDraw)
: CKeyProcess(pDateDraw){}
CArrawDown::CArrawDown(CComboBoxDraw* pComboBoxDraw)
: CKeyProcess(pComboBoxDraw){}
bool CArrawDown::IsProcess(unsigned int nChar, byte stateSysKey){
	return nChar == VK_DOWN && !(stateSysKey&0x1);
}
bool CArrawDown::Process(){
	if(m_pEditDraw){
		int offset = m_pEditDraw->GetOffsetLine(false);
		if(!offset)
			return true;
		m_pEditDraw->OffsetCursor(offset);
		return true;
	}if(m_pComboBoxDraw){
		m_pComboBoxDraw->OffsetSelection(1);
		return true;
	}else if(m_pDateDraw){
		m_pDateDraw->OffsetDay(7);
		return true;
	}
	return false;
}
/************************************************************************/
/*                         CShiftArrawRight                             */
/************************************************************************/
CShiftArrawRight::CShiftArrawRight(CEditDraw* pEditDraw)
: CKeyProcess(pEditDraw){}
bool CShiftArrawRight::IsProcess(unsigned int nChar, byte stateSysKey){
	return nChar == VK_RIGHT && stateSysKey&0x1 && !(stateSysKey&0x4);
}
bool CShiftArrawRight::Process(){
	CPoint nCurSel = m_pEditDraw->GetSel();
	nCurSel.y++;
	m_pEditDraw->OffsetCursor(1);
	m_pEditDraw->SetSel(nCurSel);
	return true;
}
/************************************************************************/
/*                         CShiftArrawLeft                              */
/************************************************************************/
CShiftArrawLeft::CShiftArrawLeft(CEditDraw* pEditDraw)
: CKeyProcess(pEditDraw){}
bool CShiftArrawLeft::IsProcess(unsigned int nChar, byte stateSysKey){
	return nChar == VK_LEFT && stateSysKey&0x1 && !(stateSysKey&0x4);
}
bool CShiftArrawLeft::Process(){
	CPoint nCurSel = m_pEditDraw->GetSel();
	nCurSel.y--;
	m_pEditDraw->OffsetCursor(-1);
	m_pEditDraw->SetSel(nCurSel);
	return true;
}
/************************************************************************/
/*                         CShiftArrawUp                                */
/************************************************************************/
CShiftArrawUp::CShiftArrawUp(CEditDraw* pEditDraw)
: CKeyProcess(pEditDraw){}
bool CShiftArrawUp::IsProcess(unsigned int nChar, byte stateSysKey){
	return nChar == VK_UP && stateSysKey&0x1 && !(stateSysKey&0x4);
}
bool CShiftArrawUp::Process(){
	CPoint nCurSel = m_pEditDraw->GetSel();
	int offset = m_pEditDraw->GetOffsetLine(true);
	if(offset){
		m_pEditDraw->OffsetCursor(offset);
		nCurSel.y += offset;
		m_pEditDraw->SetSel(nCurSel);
	}
	return true;
}
/************************************************************************/
/*                         CShiftArrawDown                              */
/************************************************************************/
CShiftArrawDown::CShiftArrawDown(CEditDraw* pEditDraw)
: CKeyProcess(pEditDraw){}
bool CShiftArrawDown::IsProcess(unsigned int nChar, byte stateSysKey){
	return nChar == VK_DOWN && stateSysKey&0x1 && !(stateSysKey&0x4);
}
bool CShiftArrawDown::Process(){
	CPoint nCurSel = m_pEditDraw->GetSel();
	int offset = m_pEditDraw->GetOffsetLine(false);
	if(offset){
		m_pEditDraw->OffsetCursor(offset);
		nCurSel.y += offset;
		m_pEditDraw->SetSel(nCurSel);
	}
	return true;
}
/************************************************************************/
/*                            CBackSpace                                */
/************************************************************************/
CBackSpace::CBackSpace(CEditDraw* pEditDraw)
: CKeyProcess(pEditDraw){}
bool CBackSpace::IsProcess(unsigned int nChar, byte stateSysKey){
	return nChar == VK_BACK;
}
bool CBackSpace::Process(){
	CPoint nCurSel = m_pEditDraw->GetSel();
	if(nCurSel.x == nCurSel.y){
		m_pEditDraw->Delete(nCurSel.y - 1);
		m_pEditDraw->OffsetCursor(-1);
	}else
		m_pEditDraw->Delete(nCurSel.x, nCurSel.y);
	return true;
}
/************************************************************************/
/*                            CDelete                                   */
/************************************************************************/
CDelete::CDelete(CEditDraw* pEditDraw)
: CKeyProcess(pEditDraw){}
bool CDelete::IsProcess(unsigned int nChar, byte stateSysKey){
	return nChar == VK_DELETE;
}
bool CDelete::Process(){
	CPoint nCurSel = m_pEditDraw->GetSel();
	if(nCurSel.x == nCurSel.y)
		m_pEditDraw->Delete(nCurSel.y);
	else
		m_pEditDraw->Delete(nCurSel.x, nCurSel.y);
	return true;
}
/************************************************************************/
/*                            CEnter                                    */
/************************************************************************/
CEnter::CEnter(CEditDraw* pEditDraw)
: CKeyProcess(pEditDraw){}
bool CEnter::IsProcess(unsigned int nChar, byte stateSysKey){
	return nChar == 13;
}
bool CEnter::Process(){
	if(!m_pEditDraw->IsChar('\n'))
		return false;
	m_pEditDraw->AddChar('\n');
	return true;
}
/************************************************************************/
/*                            CSpace                                    */
/************************************************************************/
CSpace::CSpace(CCheckBoxDraw* pCheckBoxDraw)
: CKeyProcess(pCheckBoxDraw){}
bool CSpace::IsProcess(unsigned int nChar, byte stateSysKey){
	return nChar == VK_SPACE;
}
bool CSpace::Process(){
	m_pCheckBoxDraw->ChangeValue();
	return true;
}
/************************************************************************/
/*                            CCopy                                     */
/************************************************************************/
CCopy::CCopy(CEditDraw* pEditDraw)
: CKeyProcess(pEditDraw){}
bool CCopy::IsProcess(unsigned int nChar, byte stateSysKey){
	return nChar == 67 && stateSysKey&0x4;
}
bool CCopy::Process(){
	CPoint posSel = m_pEditDraw->GetSel();
	std::tstring strValue = m_pEditDraw->GetValue();
	OpenClipboard(dynamic_cast<CWnd*>(IApplication::GetApp()->GetVisualManager()->GetMainWindow())->m_hWnd);
	EmptyClipboard();
	char* chBuffer;
	HGLOBAL hgBuffer;
	int size;
	std::tstring strResVal;
	if(posSel.x == posSel.y){
		size = ((int)strValue.size() + 1) * sizeof(TCHAR);
		strResVal = strValue;
	}else{
		size = (abs(posSel.y - posSel.x) + 1)* sizeof(TCHAR);
		strResVal.insert(strResVal.end(), strValue.begin() + posSel.x, strValue.begin() + posSel.y);
	}
	hgBuffer= GlobalAlloc(GMEM_DDESHARE, size);
	chBuffer= (char*)GlobalLock(hgBuffer);
	memcpy_s(chBuffer, size, strResVal.c_str(), size);
	GlobalUnlock(hgBuffer);
	SetClipboardData(CF_UNICODETEXT, hgBuffer);
	CloseClipboard();
	return true;
}
/************************************************************************/
/*                            CCharKey                                  */
/************************************************************************/
CCharKey::CCharKey(CEditDraw* pEditDraw)
: CKeyProcess(pEditDraw){}
bool CCharKey::IsProcess(unsigned int nChar, byte stateSysKey){
	m_nChar = nChar;
	return true;
}
bool CCharKey::Process(){
	TCHAR nChar[2] = {0};
	byte ks[256];
	HKL hkl = GetKeyboardLayout(GetCurrentThreadId());
	GetKeyboardState(ks);
	int scanCode = MapVirtualKeyEx(m_nChar,0,hkl);
	ToUnicode(m_nChar, scanCode, ks, nChar, sizeof(TCHAR), 0);
	if(!m_pEditDraw->IsChar(nChar[0]))
		return false;
	m_pEditDraw->AddChar(nChar[0]);
	return true;
}